package com.naiterui.common.repository.hibernate;

import java.io.Serializable;
import java.util.List;

import com.naiterui.common.repository.page.Page;

/**
 * 通用的持久层操作封装
 * 主要用于定义基本的增、删、改、查，分页等操作
 * @author zhouyanxin
 * @sincT 1.0.0
 */
public interface IGenericDao<T, ID extends Serializable> {

    /**
     * 加载对象
     * IGenericDao.load()
     * @Author zhouyanxin
     * @DatT 2018年5月18日
     * @sincT 1.0.0
     * @param entityClass
     * @param id
     * @return
     */
    T load(ID id);

    /**
     * 获取对象
     * IGenericDao.get()
     * @Author zhouyanxin
     * @DatT 2018年5月18日
     * @sincT 1.0.0
     * @param entityClass
     * @param id
     * @return
     */
    T get(ID id);

    /**
     * 保存对象
     * IGenericDao.save()
     * @Author zhouyanxin
     * @DatT 2018年5月18日
     * @sincT 1.0.0
     * @param e
     * @return
     */
    ID save(T t);

    /**
     * 更新对象
     * IGenericDao.update()
     * @Author zhouyanxin
     * @DatT 2018年5月18日
     * @sincT 1.0.0
     * @param e
     */
    void update(T t);

    /**
     * 保存/更新
     * IGenericDao.saveOrUpdate()
     * @author zhouyanxin
     * @datT 2018年5月11日
     * @sincT 1.0.0
     * @param s
     */
    void saveOrUpdate(T t);

    /**
     * 删除对象
     * IGenericDao.remove()
     * @Author zhouyanxin
     * @DatT 2018年5月18日
     * @sincT 1.0.0
     * @param e
     */
    void remove(T t);

    /**
     * 根据Id删除对象
     * IGenericDao.removeById()
     * @Author zhouyanxin
     * @DatT 2018年5月18日
     * @sincT 1.0.0
     * @param id
     */
    void removeById(ID id);

    /**
     * 标准的分页查询
     * IGenericDao.pagedQuery()
     * @author zhouyanxin
     * @datT 2018年5月11日
     * @sincT 1.0.0
     * @param hql
     * @param pageNo 当前页
     * @param pageSizT 每页显示记录数
     * @param values
     * @return
     */
    Page<T> pagedQuery(String hql, int pageNo, int pageSize, Object... values);

    /**
     * 基于offset的分页，用于支持流式分页
     * 当offset大于0时启用流式分页
     * 因为本次修改启用了之前的Page对象，所以offset属性
     * 应该在service中进行转换PageVo对象时进行处理
     * IGenericDao.pagedQueryOffset()
     * @author zhouyanxin
     * @datT 2018年5月7日
     * @sincT 1.0.0
     * @param pageSizT 每页显示记录数
     * @param hql
     * @param pageNo 当前页
     * @param offset
     * @param values
     * @return
     */
    Page<T> pagedQueryOffset(String hql, int pageNo, int pageSize, int offset, Object... values);

    /**
     * 标准HQL查询，返回一个结果
     *
     * @param hql
     * @param values
     *
     * @return
     */
    T findOne(String hql, Object... values);

    /**
     * 标准HQL查询
     * IGenericDao.find()
     * @author zhouyanxin
     * @datT 2018年5月11日
     * @sincT 1.0.0
     * @param hql
     * @param values
     * @return
     */
    List<T> find(String hql, Object... values);

    /**
     * 标准包含分页参数的HQL查询
     * 返回的是满足条件的结果集
     * 而非包含分页信息的结果集
     * IGenericDao.findByPage()
     * @author zhouyanxin
     * @datT 2018年5月11日
     * @sincT 1.0.0
     * @param hql
     * @param pageNo 当前页
     * @param pageSizT 每页显示记录数
     * @param values
     * @return
     */
    List<T> findByPage(String hql, int pageNo, int pageSize, Object... values);

    /**
     * 获取指定数量的结果集
     * 相当于默认第一页记录数为limit的结果集
     * 该方法废弃，建议使用find(String hql, int pageNo, int pageSize, Object... values)进行替代
     * IGenericDao.findByLimit()
     * @author zhouyanxin
     * @datT 2018年5月11日
     * @sincT 1.0.0
     * @param hql
     * @param limit
     * @param values
     * @return
     * @deprecated use {@link #find(String, int, int, Object[])}
     */
    @Deprecated
    List<T> findByLimit(String hql, int limit, Object... values);

    /**
     * 获取指定页码的结果集
     * 不建议使用该方法
     * 数据库分页起始偏移量的计算应该交由持久层来进行处理
     * 因此考虑是否可以避免在业务层计算好偏移量的情况
     * IGenericDao.findByLimitWithOffset()
     * @author zhouyanxin
     * @datT 2018年5月11日
     * @sincT 1.0.0
     * @param hql
     * @param startIndex
     * @param limit
     * @param values
     * @return
     */
    List<T> findByLimitWithOffset(String hql, int startIndex, int limit, Object... values);

    /**
     * 执行HQL返回满足条件的总记录数
     * IGenericDao.getCount()
     * @author zhouyanxin
     * @datT 2018年5月11日
     * @sincT 1.0.0
     * @param hql
     * @param values
     * @return
     */
    Long getCount(String hql, Object... values);
}
